package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.DishSetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Slf4j
@Service
public class DishServiceImpl implements DishService {
    private final DishMapper dishMapper;
    private final DishFlavorMapper dishFlavorMapper;
    private final DishSetmealMapper dishSetmealMapper;

    public DishServiceImpl(DishMapper dishMapper, DishFlavorMapper dishFlavorMapper, DishSetmealMapper dishSetmealMapper) {
        this.dishMapper = dishMapper;
        this.dishFlavorMapper = dishFlavorMapper;
        this.dishSetmealMapper = dishSetmealMapper;
    }

    /**
     * 新增菜品
     *
     * @param dto 菜品
     */
    @Transactional // 0.开启事务(涉及多表操作时)
    public void addDish(DishDTO dto) {
        // 1. 构造菜品基本信息数据，将其存入Dish表中
        // 1.1 拷贝属性值
        Dish dish = new Dish();
        BeanUtils.copyProperties(dto, dish);
        // 1.2 调用Mapper保存方法
        dishMapper.insert(dish);

        log.info("dishId={}", dish.getId());

        // 2. 构造菜品口味列表数据，将其存入dish_flavors表中
        List<DishFlavor> dishFlavorList = dto.getFlavors();

        if (dishFlavorList != null && dishFlavorList.size() > 0) {
            // 2.1 关联菜品id
            dishFlavorList.forEach(dishFlavor -> {
                dishFlavor.setDishId(dish.getId());
            });
            // 3. 调用mapper方法，批量插入口味列表数据
            dishFlavorMapper.insertBatch(dishFlavorList);
        }else{
            System.out.println("------------未写口味列表");
        }
    }

    /**
     * 分页查询菜品列表
     * @param queryDTO 请求参数
     * @return 分页结果
     */
    @Override
    public PageResult pageDish(DishPageQueryDTO queryDTO) {
        // 1. 设置分页参数
        PageHelper.startPage(queryDTO.getPage(), queryDTO.getPageSize());

        // 2. 调用Mapper
        Page<DishVO> page = dishMapper.page(queryDTO);
        // 3. 返回Result对象
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 删除菜品
     * @param ids 菜品id数组
     */
    @Override
    @Transactional
    public void deleteDish(List<Long> ids) {
        // 1.删除菜品关联的数据
        // 1.1 判断菜品数据是否是起售中（拿数据库的dish.status）
        ids.forEach(dishId -> {
            Dish dish = dishMapper.findById(dishId); // 获取菜品属性
            Integer count = dishSetmealMapper.countByDishId(dishId);
            if(dish.getStatus().equals(StatusConstant.ENABLE)){
                log.info("删除的菜品{}在起售状态",dish.getName());
                throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
            }else if(count > 0){ // 1.2 判断菜品是否被套餐关联
                log.info("删除的菜品{}存在套餐", dish.getName());
                throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
            }else {
                // 1. 删除菜品口味表
                dishFlavorMapper.deleteByDishId(dishId);

                // 2. 删除基本菜品表
                dishMapper.deleteById(dishId);
                log.info("删除菜品{}", dish.getName());
            }
        });
    }

    /**
     * 回显菜品
     * @param id 菜品
     * @return 菜品VO
     */
    @Override
    public DishVO getById(Long id) {
        // 0. 创建DishVO空对象，以便接收数据
        DishVO dishVO = new DishVO();

        // 1. 根据菜品id查询菜品基本数据,封装到DishVO
        Dish dish = dishMapper.findById(id);
        BeanUtils.copyProperties(dish, dishVO);

        // 2. 根据菜品id查询口味列表,封装到dishVO中
        List<DishFlavor> dishFlavorList = dishFlavorMapper.selectDishById(id);
        dishVO.setFlavors(dishFlavorList);

        // 3. 构造VO对象并返回
        return dishVO;
    }

    /**
     * 修改菜品
     * @param dto 菜品DTO
     *
     */
    @Override
    @Transactional
    public void update(DishDTO dto) {
        // 1.修改菜品的基本信息
        // 1.1 操作具体表一定传递表对应的对象 除非查询
        Dish dish = new Dish();
        BeanUtils.copyProperties(dto, dish);
        dishMapper.update(dish);

        // 2. 修改菜品口味信息
        // 由于口味数据可能删除，可能增加，可能修改，涉及增删改
        // 所以可以全部删除旧数据，添加新数据
        dishFlavorMapper.deleteByDishId(dish.getId());

        List<DishFlavor> flavors = dto.getFlavors();
        if (flavors != null && !flavors.isEmpty()) {
            // 关联菜品id
            flavors.forEach(dishFlavor -> {
                dishFlavor.setDishId(dish.getId());
            });
            dishFlavorMapper.insertBatch(flavors);
        }
    }


}
